package service

// 导入必要的包
import (
	"gin_im/define"
	"gin_im/helper"
	"gin_im/models"
	"github.com/gin-gonic/gin"     // Web框架
	"github.com/gorilla/websocket" // WebSocket库
	"log"
	"net/http" // HTTP功能
	"time"
)

// 创建WebSocket连接映射表：key=用户身份标识，value=WebSocket连接对象
var wc = map[string]*websocket.Conn{}

// WebSocket连接升级配置
var upgrader = websocket.Upgrader{}

// WebSocketMessage WebSocket消息处理函数
func WebSocketMessage(c *gin.Context) {
	// 升级HTTP连接到WebSocket协议
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		// 升级失败，返回错误响应
		c.JSON(http.StatusOK, gin.H{"code": -1, "msg": "系统异常：" + err.Error()})
		return
	}
	defer conn.Close() // 确保连接最终关闭

	// 从上下文中获取用户认证信息 类型断言，转换为UserClaims结构体指针
	uc := c.MustGet("user_claims").(*helper.UserClaims)
	wc[uc.Identity] = conn // 将用户WebSocket连接存入连接池：key=用户ID，value=连接对象
	// 持续监听消息
	for {
		ms := &define.MessageStruct{} // 创建消息结构体实例
		err := conn.ReadJSON(ms)      // 从WebSocket连接读取JSON消息
		// 检查消息读取是否出错
		if err != nil {
			log.Printf("Read Error:%v\n", err) // 打印读取错误日志
			return                             // 出错时退出函数
		}
		// 检查用户是否在房间中，不在则记录日志并返回
		if _, err = models.GetUserRoomByUserIdentityRoomIdentity(uc.Identity, ms.RoomIdentity); err != nil {
			log.Printf("UserIdentity: %v RoomIdentity: %v Not Exists \n", uc.Identity, ms.RoomIdentity)
			return
		}

		// TODO: 获取在特定房间的在线用户
		// 根据房间ID查询所有房间成员
		userRooms, err := models.GetUserRoomByRoomIdentity(ms.RoomIdentity)
		if err != nil {
			log.Printf("[DB ERROR]:%v\n", err) // 数据库查询失败
			return
		}

		// 保存消息到数据库
		mb := &models.MessageBasic{
			UserIdentity: uc.Identity,       // 发送者用户ID
			RoomIdentity: ms.RoomIdentity,   // 目标房间ID
			Data:         ms.Message,        // 消息内容
			CreatedAt:    time.Now().Unix(), // 创建时间戳
			UpdatedAt:    time.Now().Unix(), // 更新时间戳
		}

		// 执行数据库插入操作
		if err = models.InsertOneMessageBasic(mb); err != nil {
			log.Printf("[DB ERROR]:%v\n", err)
			return
		}

		// 遍历房间所有成员
		for _, room := range userRooms {
			// 检查用户是否在线（连接池中是否存在）
			if cc, ok := wc[room.UserIdentity]; ok {
				// 向在线用户发送消息
				err := cc.WriteMessage(websocket.TextMessage, []byte(ms.Message))
				if err != nil {
					log.Printf("Write Message Error:%v\n", err) // 消息发送失败
					return
				}
			}
		}

		// 遍历所有WebSocket连接，广播消息
		//for _, cc := range wc {
		//	// 向当前连接发送文本消息
		//	err := cc.WriteMessage(websocket.TextMessage, []byte(ms.Message))
		//
		//	// 检查消息发送是否失败
		//	if err != nil {
		//		log.Printf("Write Message Error:%v\n", err) // 打印发送错误日志
		//		return                                      // 发送失败时退出函数
		//	}
		//}

	}
}
